package org.triumphxx.util;

import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.triumphxx.ruleelements.BaseRule;
import org.triumphxx.ruleelements.RuleExecutionDTO;
import org.triumphxx.ruleexecutor.RuleExecutor;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static org.triumphxx.constant.RuleConstant.AND;
import static org.triumphxx.constant.RuleConstant.OR;

/**
 * @author:triumphxx
 * @Date: 2024/1/8
 * @Time: 16:25
 * @微信公众号：思考集结处
 * @网站：http://blog.triumphxx.com.cn
 * @GitHub https://github.com/triumphxx
 * @Desc: 规则执行工具类
 **/
@Component
public class RuleExecutorUtil {
    /**
     * 1、需要将数据集合传入
     * 2、需要将规则集合传入
     * @param objects
     * @return and 的逻辑关系需要执行全部的规则  or的只要满足一条规则直接返回
     */
    public boolean execute(Map<String, List<BaseRule>> rules ,List<Object> objects){
        //1. 定义规则  init rule  需要将不同逻辑回执的规则分类
        List<BaseRule> andRules = new ArrayList<>();
        List<BaseRule> orRules = new ArrayList<>();
        //将规则分类
        for (Map.Entry<String, List<BaseRule>> item : rules.entrySet()) {
            List<BaseRule> ruleList = item.getValue();
            switch (item.getKey()) {
                case AND:
                    andRules.addAll(ruleList);
                    break;
                case OR:
                    orRules.addAll(ruleList);
                    break;
                default:
                    break;
            }
        }
        //2. 构造需要的数据 create dto  并且将数据合并
        RuleExecutionDTO dto = new RuleExecutionDTO();
        dto.setId(1);
        for (Object object : objects) {
            BeanUtils.copyProperties(object,dto);
        }
        //3. 通过以链式调用构建和执行 rule execute
        return RuleExecutor
                .create()
                .and(andRules)
                .or(orRules)
                .execute(dto);
    }

}
